Skip to content

fix: apply FastEmbed query/passage asymmetry via query_embed - #1265

Open
Aryan-Pardeshi wants to merge 1 commit into
basicmachines-co:mainfrom
Aryan-Pardeshi:fix/fastembed-query-embed
Open

fix: apply FastEmbed query/passage asymmetry via query_embed#1265
Aryan-Pardeshi wants to merge 1 commit into
basicmachines-co:mainfrom
Aryan-Pardeshi:fix/fastembed-query-embed

Conversation

@Aryan-Pardeshi

Copy link
Copy Markdown

Summary

FastEmbedEmbeddingProvider.embed_query() delegated to embed_documents(), so asymmetric models such as bge-small-en-v1.5 embedded queries through the passage/document path and silently lost the model's query-side instruction — the retrieval-quality regression measured in #1264.

Changes

  • embed_query now routes through TextEmbedding.query_embed(text) in a worker thread, which is FastEmbed's query path for asymmetric models.
  • The L2 normalization (required by sqlite_search_repository's unit-vector distance contract) and the dimension mismatch check are shared with embed_documents via a _normalize_vectors helper — both paths keep identical post-processing.
  • Documents are untouched: embed_documents behavior, identity keys, and stored vectors stay valid, so no re-indexing is triggered.

Notes

  • semantic_embedding_document_input_type / semantic_embedding_query_input_type remain LiteLLM-only: FastEmbed has no input_type request parameter — the role split is query_embed vs embed, so no config plumbing is needed for the native provider.
  • query_embed accepts no batch_size/parallel kwargs (single query string), so the runtime knobs stay on the document path only.

Testing

  • New regression tests: query path uses query_embed (asserted distinct query vs passage vectors, and that embed is never called), plus unit-norm and dimension-mismatch coverage for query vectors.
  • Full tests/repository/ suite + semantic embedding watch tests: 654 passed, 30 skipped.
  • ruff check, ruff format --check, and ty check clean.

Closes #1264

embed_query previously delegated to embed_documents, so asymmetric models
like bge-small-en-v1.5 embedded queries through the passage path and lost
the model's query-side instruction, degrading retrieval quality (basicmachines-co#1264).

Route embed_query through TextEmbedding.query_embed, sharing the existing
L2 normalization and dimension checks with embed_documents via a
_normalize_vectors helper. Documents are unaffected, so stored vectors and
identity keys stay valid.

Closes basicmachines-co#1264
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4e0ba28bdb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# silently loses that asymmetry for queries (#1264). query_embed takes no
# batch/parallel kwargs — it embeds a single query string.
def _embed_query() -> list[list[float]]:
return self._normalize_vectors(model.query_embed(text))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Apply the actual FastEmbed query instruction

For the default bge-small-en-v1.5 path this still embeds the raw query through the same ONNX embed path: in FastEmbed 0.8.0, TextEmbedding.query_embed only delegates to the selected model, and the base string implementation calls self.embed([query], **kwargs) (source, source). Therefore the #1264 scenario for the default FastEmbed model still produces the same vector as before, while the new stub test invents a distinct query vector; if the fix is meant to restore the BGE query role, this path needs to add/use the actual role prefix or otherwise exercise real FastEmbed behavior rather than just switching method names.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FastEmbed provider never applies query/passage asymmetry, silently breaking asymmetric models (multilingual-e5)

2 participants